package com.yun.zf.admin.service.impl;

import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yun.zf.admin.mapper.*;
import com.yun.zf.admin.service.*;
import com.yun.zf.common.admin.dto.HousePactMo;
import com.yun.zf.common.admin.dto.community.AgentInfoDto;
import com.yun.zf.common.admin.dto.house.*;
import com.yun.zf.common.admin.model.house.HouseDescMo;
import com.yun.zf.common.admin.model.house.HouseInfo;
import com.yun.zf.common.admin.model.house.HouseListMo;
import com.yun.zf.common.admin.model.house.es.*;
import com.yun.zf.common.admin.model.search.HouseIndexKey;
import com.yun.zf.common.admin.model.search.HouseSearchMo;
import com.yun.zf.common.app.domain.ZfCommunity;
import com.yun.zf.common.app.domain.ZfHouseBasic;
import com.yun.zf.common.app.domain.ZfHouseScore;
import com.yun.zf.common.app.dto.community.CommunityTotal;
import com.yun.zf.common.constant.Constants;
import com.yun.zf.common.esIndex.HouseIndexTemplate;
import com.yun.zf.common.esIndex.HouseRentIndexTemplate;
import com.yun.zf.common.esRes.HouseIndexResMo;
import com.yun.zf.common.mapstruct.admin.HouseMapper;
import com.yun.zf.common.vo.Response;
import com.yun.zf.system.security.utils.SecurityUtils;
import com.yun.zf.system.utils.EsRestUtil;
import lombok.extern.java.Log;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;

@Service
@Log
public class ZfHouseBasicServiceImpl extends ServiceImpl<ZfHouseBasicMapper, ZfHouseBasic> implements ZfHouseBasicService {

    @Autowired
    private EsRestUtil esRestUtil;
    @Autowired
    private ZfDeptCommunityService deptCommunityService;
    @Autowired
    private ZfHousePictureService pictureService;
    @Autowired
    private ZfHouseDetailMapper detailMapper;
    @Autowired
    private ZfCommunityService communityService;
    @Autowired
    private ZfHouseInfoService houseInfoService;
    @Autowired
    private ZfHouseDescService houseDescService;
    @Autowired
    private ZfHouseBasicMapper basicMapper;
    @Autowired
    private ZfHouseInfoMapper infoMapper;
    @Autowired
    private ZfHouseInfoRentMapper rentMapper;
    @Autowired
    private ZfHouseInfoSaleMapper saleMapper;
    @Autowired
    private ZfHouseScoreService scoreService;
    @Autowired
    private ZfHouseDocumentInfoService documentInfoService;

    /**
     * 录入房屋基本信息，返回房源id
     *
     * @param houseBasic
     * @return
     */
    @Override
    @Transactional
    public Long addHouseBasic(ZfHouseBasic houseBasic) {
        baseMapper.insert(houseBasic);
        return houseBasic.getId();
    }

    /**
     * 查询房源基本信息是否已录入
     *
     * @param id
     * @param provinceCode
     * @param cityCode
     * @return
     */
    @Override
    public int selectHouseBasic(Long id, Long provinceCode, Long cityCode) {
        QueryWrapper<ZfHouseBasic> houseBasicQueryWrapper = new QueryWrapper<>();
        houseBasicQueryWrapper.lambda().eq(ZfHouseBasic::getId, id).eq(ZfHouseBasic::getProvinceCode, provinceCode)
                .eq(ZfHouseBasic::getCityCode, cityCode);
        int count = baseMapper.selectCount(houseBasicQueryWrapper);
        return count;
    }

    @Override
    public ZfHouseBasic getHouseBasic(Long id, Long provinceCode, Long cityCode) {
        QueryWrapper<ZfHouseBasic> houseBasicQueryWrapper = new QueryWrapper<>();
        houseBasicQueryWrapper.lambda().eq(ZfHouseBasic::getId, id).eq(ZfHouseBasic::getProvinceCode, provinceCode)
                .eq(ZfHouseBasic::getCityCode, cityCode);
        return baseMapper.selectOne(houseBasicQueryWrapper);
    }

    @Override
    public Map<String, Object> searchHouseBasic(HouseSearchMo searchMo) {
        NativeSearchQueryBuilder searchQueryBuilder = new NativeSearchQueryBuilder();
        // 查询只返回小区ID 字段
        String[] fields = new String[]{HouseIndexKey.HID, HouseIndexKey.PROVINCECODE, HouseIndexKey.CITYCODE};
        //1 、 构建搜索条件
        BoolQueryBuilder queryBuilder = QueryBuilders.boolQuery();

        // 2、城市代码必传-----
        queryBuilder.must(QueryBuilders.termQuery(HouseIndexKey.CITYCODE, searchMo.getCityCode()));
        // 3、类型type必传-----
        queryBuilder.must(QueryBuilders.termQuery(HouseIndexKey.TYPE, searchMo.getType()));
        // 4、 房源编号不为空直接匹配
        if (StringUtils.isNotBlank(searchMo.getHouseNumber())) {
            queryBuilder.filter(QueryBuilders.termQuery(HouseIndexKey.HOUSENUMBER, searchMo.getHouseNumber()));
        }
        // 5、 匹配区域代码
        if (StringUtils.isNotBlank(searchMo.getRegionCode()) && !"BX".equals(searchMo.getRegionCode())) {
            queryBuilder.filter(QueryBuilders.termQuery(HouseIndexKey.REGIONCODE, searchMo.getRegionCode()));
        }
        // 6、 匹配街道代码
        if (StringUtils.isNotBlank(searchMo.getStreetCode()) && !"BX".equals(searchMo.getStreetCode())) {
            queryBuilder.filter(QueryBuilders.termQuery(HouseIndexKey.STREETCODE, searchMo.getStreetCode()));
        }
        //7、小区ID 匹配
        if (StringUtils.isNotBlank(searchMo.getCommunityId())) {
            String[] communityids = searchMo.getCommunityId().split(",");
            queryBuilder.filter(QueryBuilders.termsQuery(HouseIndexKey.communityId, communityids));
        }

        // 8、如果价格区间不为空则加上价格搜索
        if (StringUtils.isNotBlank(searchMo.getHopedPrice()) && !"BX".equals(searchMo.getHopedPrice())) {
            String minPrice = searchMo.getHopedPrice().split("-")[0];
            String maxPrice = searchMo.getHopedPrice().split("-")[1];
            queryBuilder.filter(QueryBuilders.rangeQuery(HouseIndexKey.HOPEDPRICE).gte(minPrice).lte(maxPrice));
        }

        // 9、匹配面积区间
        if (StringUtils.isNotBlank(searchMo.getArea()) && !"BX".equals(searchMo.getArea())) {
            String minArea = searchMo.getArea().split("-")[0];
            String maxArea = searchMo.getArea().split("-")[1];
            queryBuilder.filter(QueryBuilders.rangeQuery(HouseIndexKey.AREA).gte(minArea).lte(maxArea));
        }
        // 10.匹配房型
        if (StringUtils.isNotBlank(searchMo.getBedrooms()) && !"BX".equals(searchMo.getBedrooms())) {
            queryBuilder.filter(QueryBuilders.termQuery(HouseIndexKey.BEDROOMS, searchMo.getBedrooms()));
        }
        // todo 待补充查询条件-----
        // 11、匹配标签
        String tags = searchMo.getTags();
        if (StringUtils.isNotBlank(tags) && !"BX".equals(tags)) {
            String[] tgs = tags.split(",");
            queryBuilder.filter(QueryBuilders.termsQuery(HouseIndexKey.TAGS, tgs));
        }
        // 12 匹配朝向 ，注意，这里使用的text 放入ES 中的数据不要为中文，容易被分词导致搜索不到
        if (StringUtils.isNotBlank(searchMo.getDirection()) && !"BX".equals(searchMo.getDirection())) {
            String[] directions = searchMo.getDirection().split(",");
            queryBuilder.filter(QueryBuilders.termsQuery(HouseIndexKey.DIRECTION, directions));
        }
        //14 匹配楼层
        if (StringUtils.isNotBlank(searchMo.getFloorTag()) && !"BX".equals(searchMo.getFloorTag())) {
            String[] floors = searchMo.getFloorTag().split(",");
            queryBuilder.filter(QueryBuilders.termsQuery(HouseIndexKey.FLOORTAG, floors));
        }
        // 15.匹配电梯
        if (StringUtils.isNotBlank(searchMo.getIsElevator()) && !"BX".equals(searchMo.getIsElevator())) {
            queryBuilder.filter(QueryBuilders.termQuery(HouseIndexKey.ISELEVATOR, searchMo.getIsElevator()));
        }
        // 16、匹配装修
        if (StringUtils.isNotBlank(searchMo.getFixtures()) && !"BX".equals(searchMo.getFixtures())) {
            String[] fixtures = searchMo.getFixtures().split(",");
            queryBuilder.filter(QueryBuilders.termsQuery(HouseIndexKey.FIXTURES, fixtures));
        }
        // 17.匹配楼龄
        if (StringUtils.isNotBlank(searchMo.getBuildYear()) && !"BX".equals(searchMo.getBuildYear())) {
            int minYear = Integer.parseInt(searchMo.getBuildYear().split("-")[0]);
            int maxYear = Integer.parseInt(searchMo.getBuildYear().split("-")[1]);
            int startYear = DateUtil.thisYear() - minYear;
            int ednYear = DateUtil.thisYear() - maxYear;
            // todo
            queryBuilder.filter(QueryBuilders.rangeQuery(HouseIndexKey.BUILDYEAR).gte(startYear).lte(ednYear));
        }

        // 18.匹配用途
        if (StringUtils.isNotBlank(searchMo.getHouseUse()) && !"BX".equals(searchMo.getHouseUse())) {
            String[] houseUses = searchMo.getHouseUse().split(",");
            queryBuilder.filter(QueryBuilders.termsQuery(HouseIndexKey.HOUSEUSE, houseUses));
        }
        // 16.匹配权属- 商品房。公房等
        if (StringUtils.isNotBlank(searchMo.getOwnerShip()) && !"BX".equals(searchMo.getOwnerShip())) {
            String[] ships = searchMo.getOwnerShip().split(",");
            queryBuilder.filter(QueryBuilders.termsQuery(HouseIndexKey.OWNERSHIP, ships));
        }

        // 17.匹配类型
        if (StringUtils.isNotBlank(searchMo.getBuildingType()) && !"BX".equals(searchMo.getBuildingType())) {
            String[] buildTypes = searchMo.getBuildingType().split(",");
            queryBuilder.filter(QueryBuilders.termsQuery(HouseIndexKey.BUILDINGTYPE, buildTypes));
        }

        // 出租方式匹配
        if (StringUtils.isNotBlank(searchMo.getRentType()) && !"BX".equals(searchMo.getRentType())) {
            queryBuilder.filter(QueryBuilders.termQuery(HouseIndexKey.RENTTYPE, searchMo.getRentType()));
        }
        // 匹配租期分两部分，年租 匹配单位年， 短租匹配单位为月
        if (StringUtils.isNotBlank(searchMo.getUnit()) && !"BX".equals(searchMo.getUnit())) {
            queryBuilder.filter(QueryBuilders.termQuery(HouseIndexKey.UNIT, searchMo.getUnit()));
        }


        searchQueryBuilder.withQuery(queryBuilder).withFields(fields);
        try {
            String index = "";
            if (searchMo.getType() == 1) {
                index = Constants.ES_HOUSE_RENT_INDEX;
            } else if (searchMo.getType() == 2) {
                index = Constants.ES_HOUSE_INDEX;
            }

            Map<String, Object> communityData = esRestUtil.searchDataPage(index, searchMo.getCurrent(), searchMo.getPageSize(), HouseIndexResMo.class, searchQueryBuilder);
            return communityData;
        } catch (Exception e) {

        }
        return null;
    }

    /**
     * 获取详情信息
     *
     * @param houseId
     * @param provCode
     * @param cityCode
     */
    @Override
    public House getHouseAllInfo(Long houseId, Long provCode, Long cityCode) {
        //1、获取图片信息
        List<AdminHousePicDto> pictures = pictureService.getPics(houseId, provCode, cityCode);
        //3、 房源基础信息
        HouseDetailAdminDto houseBasic = basicMapper.getBasicInfo(houseId, provCode, cityCode);
        //4、 小区基础信息
        ZfCommunity community = communityService.findommunityBasic(Long.parseLong(houseBasic.getCommunityId()));
        // 5、 获取维护信息
        HouseInfo houseInfo = houseInfoService.getHouseInfoById(houseId, provCode, cityCode);
        // 6 获取房源特色信息
        HouseDescMo houseDesc = houseDescService.getHouseDes(houseId, provCode, cityCode);
        //7 同小区房源
        Page<HouseListMo> chouse = houseBasic(provCode, cityCode, Long.parseLong(houseBasic.getCommunityId()), houseBasic.getType(),houseId, 1, 5);
        // 经纪人列表
        List<AgentInfoDto> agents = deptCommunityService.getAgentInfo(Long.parseLong(houseBasic.getCommunityId()));
        // 查询得分情况
        ZfHouseScore score = scoreService.getHouseScore(houseId, cityCode, provCode);
        // 证件上传时间及状态
        List<DocumentCountDto> documentInfo =documentInfoService.getDocumentInfo(houseId,provCode,cityCode);
        House house = new House();
        house.setHousePictures(pictures);
        house.setHouseBasic(houseBasic);
        house.setCommunity(community);
        house.setHouseInfo(houseInfo);
        house.setHouseDesc(houseDesc);
        house.setChouse(chouse);
        house.setAgents(agents);
        if (score!=null){
            house.setAvgScore(score.getAvgScore());
            house.setAvgRate(score.getAvgRate());
        }

        house.setDoc(documentInfo);
        return house;
    }

    /**
     * 查询当前业务员是否有修改当前数据权限
     *
     * @param houseId
     * @param provCode
     * @param cityCode
     * @param agentNo
     * @return
     */
    @Override
    public int selectCountByBasicId(Long houseId, Long provCode, Long cityCode, int agentNo) {
        QueryWrapper<ZfHouseBasic> detailQueryWrapper = new QueryWrapper<>();
        detailQueryWrapper.lambda().eq(ZfHouseBasic::getProvinceCode, provCode)
                .eq(ZfHouseBasic::getRecordUser, agentNo)
                .eq(ZfHouseBasic::getCityCode, cityCode).eq(ZfHouseBasic::getId, houseId);
        return baseMapper.selectCount(detailQueryWrapper);
    }

    /**
     * 查询业务员维护的房源
     *
     * @param provCode
     * @param cityCode
     * @param agentNo
     * @return
     */
    @Override
    public Page<HouseListMo> houseBasic(Long provCode, Long cityCode, int agentNo, int current, int pageSize,int type) {
        Page<HouseListMo> page = new Page<>(current, pageSize);
        List<HouseListMo> list = baseMapper.getHouseListByAgent(provCode, cityCode, agentNo, page,type);
        if (list != null && list.size() > 0) {
            for (HouseListMo mo : list
            ) {
                List<AdminHousePicDto> pics = pictureService.getPics(Long.parseLong(mo.getId()), provCode, cityCode, 1);
                if (pics.size() > 0) {
                    mo.setUrl(pics.get(0).getUrl());
                }
            }
        }
        page.setRecords(list);
        return page;
    }

    @Override
    public Page<HouseListMo> houseBasic(Long provCode, Long cityCode, Long communityId, int type,Long houseId ,int current, int pageSize) {
        Page<HouseListMo> page = new Page<>(current, pageSize);
        List<HouseListMo> list = baseMapper.getHouseListByCommunity(provCode, cityCode, communityId, type,houseId, page);
        if (list != null && list.size() > 0) {
            for (HouseListMo mo : list
            ) {
                List<AdminHousePicDto> pics = pictureService.getPics(Long.parseLong(mo.getId()), provCode, cityCode, 1);
                if (pics.size() > 0) {
                    mo.setUrl(pics.get(0).getUrl());
                }
            }
        }
        page.setRecords(list);
        return page;
    }

    @Override
    public List<HouseListMo> houseBasic(Long provCode, Long cityCode, List<Long> ids) {
        List<HouseListMo> list = basicMapper.getHouseList(provCode, cityCode, ids);
        if (list != null && list.size() > 0) {
            for (HouseListMo mo : list
            ) {
                List<AdminHousePicDto> pics = pictureService.getPics(Long.parseLong(mo.getId()), provCode, cityCode, 1);
                if (pics.size() > 0) {
                    mo.setUrl(pics.get(0).getUrl());
                }
            }
        }
        return list;
    }

    /**
     * 创建合同根据房源编号查询房源基本信息确认是否有错
     *
     * @param houseNumber
     * @param cityCode
     * @param provCode
     * @return
     */
    @Override
    public HousePactMo searchHouseInfoToPact(String houseId, Long cityCode, Long provCode) {

        return basicMapper.getHousePact(Long.parseLong(houseId) , cityCode, provCode);
    }

    /**
     * 签约创建订单合同后更新房源状态，暂时锁定，如果取消订单则在更新房源状态
     *
     * @param basicId  房源id
     * @param cityCode
     * @param provCode
     * @return
     */
    @Override
    public int updateStatusAfterPact(Long basicId, Long cityCode, Long provCode, String status) {
        QueryWrapper<ZfHouseBasic> basicQueryWrapper = new QueryWrapper<>();
        basicQueryWrapper.lambda().eq(ZfHouseBasic::getId, basicId).eq(ZfHouseBasic::getCityCode, cityCode).eq(ZfHouseBasic::getProvinceCode, provCode);
        ZfHouseBasic houseBasic = baseMapper.selectOne(basicQueryWrapper);
        houseBasic.setStatus(status);
        return baseMapper.update(houseBasic, basicQueryWrapper);
    }

    /**
     * 通过小区ID 获取房源总数
     *
     * @param provCode
     * @param cityCode
     * @param
     * @return
     */
    @Override
    public List<CommunityTotal> brandHouseTotal(Long provCode, Long cityCode) {
        return baseMapper.getHouseByType(provCode, cityCode);
    }

    @Override
    public List<ZfHouseBasic> getUnmaintainhouseBasic(List<Long> ids, Long provCode, Long cityCode) {
        QueryWrapper<ZfHouseBasic> basicQueryWrapper = new QueryWrapper<>();
        basicQueryWrapper.lambda().eq(ZfHouseBasic::getStatus, "unmaintain").in(ZfHouseBasic::getCommunityId, ids).
                eq(ZfHouseBasic::getCityCode, cityCode).eq(ZfHouseBasic::getProvinceCode, provCode);
        return baseMapper.selectList(basicQueryWrapper);
    }

    /**
     * 申请维护房源，添加维护人及修改状态
     *
     * @param basicId
     * @param cityCode
     * @param provCode
     * @return
     */
    @Override
    public int updateStatusForMaintain(Long basicId, Long cityCode, Long provCode) {
        QueryWrapper<ZfHouseBasic> basicQueryWrapper = new QueryWrapper<>();
        basicQueryWrapper.lambda().eq(ZfHouseBasic::getId, basicId).eq(ZfHouseBasic::getCityCode, cityCode).eq(ZfHouseBasic::getProvinceCode, provCode);
        ZfHouseBasic houseBasic = baseMapper.selectOne(basicQueryWrapper);
        houseBasic.setStatus("checking");
        int agentNo = SecurityUtils.getLoginUser().getAgentNo();
        houseBasic.setRecordUser(agentNo);
        houseBasic.setRecordName(SecurityUtils.getLoginUser().getAgentName());
        return baseMapper.update(houseBasic, basicQueryWrapper);
    }

    @Override
    public Response houseToEs(Long houseId, Long provCode, Long cityCode) {
        try {
            // 获取基本信息
            BasicEs basic = basicMapper.basicEs(houseId, provCode, cityCode);
            // 详情信息
            DetailEs detailEs = detailMapper.detailToEs(houseId, provCode, cityCode);
            HouseInfoEs infoEs = infoMapper.infoToEs(houseId, provCode, cityCode);

            if (basic.getType() == 1) {
                RentEs rentEs = rentMapper.rentToEs(houseId, provCode, cityCode);
                HouseRentIndexTemplate rentIndexTemplate = HouseMapper.INSTANCE.houseInfoToRentIndex(basic, detailEs, infoEs, rentEs);
                esRestUtil.addDataRest(rentIndexTemplate, Constants.ES_HOUSE_RENT_INDEX, houseId.toString());
            } else if (basic.getType() == 2) {
                SaleEs saleEs = saleMapper.saleToEs(houseId, provCode, cityCode);
                HouseIndexTemplate indexTemplate = HouseMapper.INSTANCE.houseInfoToIndex(basic, detailEs, infoEs, saleEs);
                esRestUtil.addDataRest(indexTemplate, Constants.ES_HOUSE_INDEX, houseId.toString());
            }
            // 更新房源发布时间
            baseMapper.updatePushTime(houseId,provCode,cityCode);

            return Response.success();
        } catch (Exception e) {
            return Response.error("推送失败");
        }

    }

    @Override
    public CommunityTotal getDetailMaxAndMin(Long provCode, Long cityCode, Long communityId, int type) {
        return basicMapper.getDetailMaxAndMin(provCode, cityCode, communityId, type);
    }

    @Override
    public PactHouseDto getPactHouseInfo(Long houseId, Long provCode, Long cityCode) {
        return basicMapper.getPactHouseInfo(houseId, provCode, cityCode);
    }

    @Override
    public List<Map<String, Object>>  getAgent(Long houseId, Long provCode, Long cityCode) {
      QueryWrapper<ZfHouseBasic> wrapper = new QueryWrapper<>();
      wrapper.select("record_name","record_user","dept_id").lambda().eq(ZfHouseBasic::getId,houseId)
              .eq(ZfHouseBasic::getCityCode,cityCode).eq(ZfHouseBasic::getProvinceCode,provCode);
      return  baseMapper.selectMaps(wrapper);
    }
}
